import ArrayUtil from '@/ArrayUtil';
import BaseUtil from '@/BaseUtil';
import ColorStr from '@/ColorStr';
import PlayerUtil from '@/PlayerUtil';
import SelectUtil from '@/SelectUtil';
import SyncUtil from '@/SyncUtil';
import AbilityBase from 'code/Scripts/Abilities/base/AbilityBase';
import HeroHelper from 'code/Scripts/HeroHelper';

declare global {
    interface HeroSkillModel {
        hero: unit;
        skillIds: string[];
    }
}

const 玩家颜色: string[] = [ColorStr.red, ColorStr.blue, ColorStr.lumber, ColorStr.purple, ColorStr.yellow, ColorStr.orange];

export default class UIHeroSkillModel {
    DB: Map<player, HeroSkillModel> = new Map();
    constructor() {
        // 英雄使用技能书事件
        se.onUnitUseItem(this.onHeroUseItem.bind(this));

        // 在英雄创建时初始化数据
        se.on('created_hero', ({ player, hero }) => {
            this.DB.set(player, { hero, skillIds: [] });
        });

        SyncUtil.onSyncObjData('hero_forget_skill', this.forgetHeroSkill.bind(this));
    }
    forgetHeroSkill(p: player, { id }: { p: player; id: string }) {
        let list = this.DB.get(p).skillIds;
        ArrayUtil.removeElement(list, id);

        // 从单位身上删除技能
        let sk = ClassAbilityMangerInstance.getClassAbilityById(id);
        if (sk) {
            let h = SelectUtil.getAnHero(GetPlayerId(p));
            sk.remove(h);
        }

        se.emit('hero_skill_forget', { p, id });
    }
    onHeroUseItem() {
        let u = GetTriggerUnit();
        let item = GetManipulatedItem();
        let type = id2string(GetItemTypeId(item));
        this.addSkillToHero(u, type);
    }
    addSkillToHero(u: unit, type: string) {
        // 如果使用的是助手
        if (GetUnitTypeId(u) == FourCC('ehep')) {
            u = HeroHelper.DB.get(u);
        }
        let db = this.DB.get(GetOwningPlayer(u));
        if (db == null) return;
        let skid = GlobalDB.ItemDB.getSkillIdByBookId(type);
        if (skid == null) return;
        let sk = ClassAbilityMangerInstance.getClassAbilityById(skid);
        if (sk == null) return;
        // 取已经学习的技能的数量
        let count = db.skillIds.length;
        let list = db.skillIds;
        if (count >= 6) {
            // 查找是否有相同的技能
            if (list.includes(skid)) {
                this._heroLearnSkill(u, sk, type);
            } else {
                DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, `每个英雄最多只能学习6个技能！如果要更换技能，请先将旧技能删除！`);
                BaseUtil.runLater(0.1, () => {
                    UnitAddItemById(u, type);
                });
            }
        } else {
            // 直接学习技能
            this._heroLearnSkill(u, sk, type);
        }
    }
    private _heroLearnSkill(u: unit, sk: AbilityBase, type: string) {
        let lv = GetUnitAbilityLevel(u, sk.id);
        if (lv >= 6) {
            DisplayTextToPlayer(GetOwningPlayer(u), 0, 0, `技能：|cffffcc00${sk.abilityName}|r 已经满级了！无涯继续提升了`);
            BaseUtil.runLater(0.1, () => {
                UnitAddItemById(u, type);
            });
            return;
        }
        sk.addAbility(u);
        if (lv == 0) {
            PlayerUtil.message(`${玩家颜色[GetPlayerId(GetOwningPlayer(u))]}${GetPlayerName(GetOwningPlayer(u))}|r 的 |cffffff00${GetUnitName(u)}|r 学习了技能：|cff00ee00${sk.abilityName}`);
            // 记录已经学习的技能
            this.DB.get(GetOwningPlayer(u)).skillIds.push(sk.id);
            // 通知其它模块
            se.emit('hero_skill_level_up', { p: GetOwningPlayer(u), id: sk.id });
        } else {
            PlayerUtil.message(`${玩家颜色[GetPlayerId(GetOwningPlayer(u))]}${GetPlayerName(GetOwningPlayer(u))}|r 的 |cffffff00${GetUnitName(u)}|r 升级了技能：|cff00ee00${sk.abilityName}`);
        }
    }
}
